package net.zoneland.zrdp.common.utils;

import java.util.*;
import java.util.stream.Collectors;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;

import net.zoneland.zrdp.common.constant.CacheConstants;
import net.zoneland.zrdp.common.core.domain.entity.SysDictData;
import net.zoneland.zrdp.common.core.redis.RedisService;
import net.zoneland.zrdp.common.utils.spring.SpringUtils;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.apache.commons.collections4.CollectionUtils;

/**
 * 字典工具类
 *
 * @author zonevue
 */
public class DictUtils {
    private static final Logger LOGGER = LoggerFactory.getLogger(DictUtils.class);
    /**
     * 分隔符
     */
    public static final String SEPARATOR = ",";

    private DictUtils() {
        throw new IllegalStateException("Utility class");
    }

    /**
     * 设置字典缓存
     *
     * @param key 参数键
     * @param dictDatas 字典数据列表
     */
    public static void setDictCache(final String key, final List<SysDictData> dictDatas) {
        try {
            SpringUtils.getBean(RedisService.class).setCacheString(getCacheKey(key), JacksonUtils.toJsonString(dictDatas));
        } catch (final JsonProcessingException e) {
            LOGGER.error("json 序列化出错{}", key, e);
        }
    }

    /**
     * 获取字典缓存
     *
     * @param key 参数键
     * @return dictDatas 字典数据列表
     */
    public static List<SysDictData> getDictCache(final String key)  {
        final String cacheString = SpringUtils.getBean(RedisService.class).getCacheString(getCacheKey(key));
        if (Objects.nonNull(cacheString)) {
            try {
                return JacksonUtils.toTypeObject(cacheString, new TypeReference<List<SysDictData>>(){});
            } catch (final JsonProcessingException e) {
                LOGGER.error("json 反序列化出错{}", key, e);
                return Collections.emptyList();
            }
        }
        return Collections.emptyList();
    }

    /**
     * 根据字典类型和字典值获取字典标签
     *
     * @param dictType 字典类型
     * @param dictValue 字典值
     * @return 字典标签
     */
    public static String getDictLabel(final String dictType, final String dictValue) {
        return getDictLabel(dictType, dictValue, SEPARATOR);
    }

    /**
     * 根据字典类型和字典标签获取字典值
     *
     * @param dictType 字典类型
     * @param dictLabel 字典标签
     * @return 字典值
     */
    public static String getDictValue(final String dictType, final String dictLabel) {
        return getDictValue(dictType, dictLabel, SEPARATOR);
    }

    /**
     * 根据字典类型和字典值获取字典标签
     *
     * @param dictType 字典类型
     * @param dictValue 字典值
     * @param separator 分隔符
     * @return 字典标签
     */
    public static String getDictLabel(final String dictType, final String dictValue, final String separator) {
        final List<SysDictData> datas = getDictCache(dictType);

        if (CollectionUtils.isEmpty(datas)) {
            return "";
        }

        if (StringUtils.containsAny(dictValue, separator)) {
            final Set<String> valueSet = new HashSet<>(Arrays.asList(StringUtils.split(dictValue, separator)));

            return datas.stream()
                .filter(dict -> valueSet.contains(dict.getDictValue()))
                .map(SysDictData::getDictLabel)
                .collect(Collectors.joining(separator));
        } else {
            return datas.stream()
                .filter(dict -> dictValue.equals(dict.getDictValue()))
                .map(SysDictData::getDictLabel)
                .findFirst()
                .orElse("");
        }
    }


    /**
     * 根据字典类型和字典标签获取字典值
     *
     * @param dictType 字典类型
     * @param dictLabel 字典标签
     * @param separator 分隔符
     * @return 字典值
     */

    public static String getDictValue(final String dictType, final String dictLabel, final String separator) {
        final List<SysDictData> datas = getDictCache(dictType);

        if (CollectionUtils.isEmpty(datas)) {
            return "";
        }

        if (StringUtils.containsAny(dictLabel, separator)) {
            final Set<String> valueSet = new HashSet<>(Arrays.asList(StringUtils.split(dictLabel, separator)));

            return datas.stream()
                .filter(dict -> valueSet.contains(dict.getDictLabel()))
                .map(SysDictData::getDictValue)
                .collect(Collectors.joining(separator));
        } else {
            return datas.stream()
                .filter(dict -> dictLabel.equals(dict.getDictLabel()))
                .map(SysDictData::getDictValue)
                .findFirst()
                .orElse("");
        }
    }
    /**
     * 删除指定字典缓存
     *
     * @param key 字典键
     */
    public static void removeDictCache(final String key) {
        SpringUtils.getBean(RedisService.class).deleteObject(getCacheKey(key));
    }

    /**
     * 清空字典缓存
     */
    public static void clearDictCache() {
        final Collection<String> keys = SpringUtils.getBean(RedisService.class).keys(CacheConstants.SYS_DICT_KEY + "*");
        SpringUtils.getBean(RedisService.class).deleteObject(keys);
    }

    /**
     * 设置cache key
     *
     * @param configKey 参数键
     * @return 缓存键key
     */
    public static String getCacheKey(final String configKey) {
        return CacheConstants.SYS_DICT_KEY + configKey;
    }
}
